/**
 * 
 */
package freedom.sample.service.impl;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import freedom.sample.enums.Operation;
import freedom.sample.exception.UnsupportedException;
import freedom.sample.model.OrganCustomParam;
import freedom.sample.model.OrganRule;
import freedom.sample.model.RuleInEngine;
import freedom.sample.model.RuleParam;
import freedom.sample.model.RuleTemplate;
import freedom.sample.service.RuleBuilder;
import freedom.sample.service.RuleService;

import java.util.Set;

/**
 * @author charlie
 *
 */
public class RuleBuilderImpl implements RuleBuilder{
	
	public static final int days = -1;//若干天
	
	private RuleService ruleService;
	
	/* (non-Javadoc)
	 * @see freedom.sample.service.RuleBuilder#buildRulesForEnginInit()
	 */
	public Set<RuleInEngine> buildRulesForEnginInit() throws UnsupportedException {
		List<RuleTemplate> ruleTemplates = ruleService.findAllEnabledRuleTemplates();//获取所有事件规则模版(启用的)
		
		Set<Long> ruleTemplateIds = new HashSet<Long>();
		for (int i = 0; i < ruleTemplates.size(); i++) {
			ruleTemplateIds.add(ruleTemplates.get(i).getId());
		}
		List<RuleParam> ruleParams = ruleService.findRuleParamsByRuleTemplateId(ruleTemplateIds);//获取所有事件规则模版参数(模版启用的)
		
		List<OrganRule> organRules = ruleService.findAllEnabledOrganRules();//获得所有机构事件配置信息(启用的)
		Set<Long> ruleTemplateIds2 = new HashSet<Long>();
		for (int i = 0; i < organRules.size(); i++) {
			ruleTemplateIds2.add(organRules.get(i).getRuleTemplateId());
		}
		
		List<OrganCustomParam> organCustomParams = ruleService.findAllOrganCustomParamsByRuleTemplateId(ruleTemplateIds2);//获得所有机构的自定义参数(模版启用的)
		
		Map<Long, RuleTemplate> ruleTemplatesMap = toMap1(ruleTemplates);
		Map<Long, List<RuleParam>> ruleParamsMap = toMap2(ruleParams);
		
		Map<String, OrganCustomParam> organCustomParamsMap = toMap3(organCustomParams);
		
		Set<RuleInEngine> rules = new HashSet<RuleInEngine>();
		Date now = new Date();
		String weblogicNode = null;//TODO
		for (OrganRule organRule : organRules) {
			Long ruleTemplateId = organRule.getRuleTemplateId();
			RuleTemplate ruleTemplate = ruleTemplatesMap.get(ruleTemplateId);
			if(ruleTemplate == null)
				continue;
			organRule.setRuleTemplate(ruleTemplate);
			RuleInEngine rule = new RuleInEngine();
			List<RuleParam> params = ruleParamsMap.get(ruleTemplateId);
			if(params != null)
				for (RuleParam ruleParam : params) {
					String key2 = organRule.getOrganNo() + "&" + ruleParam.getId();
					OrganCustomParam organCustomParam = organCustomParamsMap.get(key2);
					if(organCustomParam == null) {
						organCustomParam = new OrganCustomParam();
						organCustomParam.setRuleParam(ruleParam);
						organCustomParam.setRuleTemplateId(ruleTemplateId);
						//TODO
					}
					rule.getParams().add(organCustomParam);
				}
			
			rule.setClusterNode(weblogicNode);
			rule.setOrganNo(organRule.getOrganNo());
			rule.setRuleTemplate(organRule.getRuleTemplate());
			rule.setRuleTemplateId(organRule.getRuleTemplateId());
			rule.setCreateTime(now);
			rule.setOperation(Operation.ENABLE);
			buildRuleText(rule);
			rules.add(rule);
		}
		return rules;
	}
	
	public Set<RuleInEngine> buildRulesForEnginInit2() {
			Set<RuleInEngine> rules = new HashSet<RuleInEngine>();
	/*		
		Date now = new Date();
		String weblogicNode = null;//TODO
		
		for (RuleTemplate ruleTemplate : ruleTemplates) {
			for (OrganRule organRule : organRules) {
				RuleInEngine rule = new RuleInEngine();
				rule.setClusterNode(weblogicNode);
				rule.setOrganNo(organRule.getOrganNo());
				rule.setTplCode(ruleTemplate.getCode());
				rule.setRuleTemplate(ruleTemplate);
				rule.setCreateTime(now);
				if(ruleTemplate.getStatus() == RuleStatus.ENABLED && organRule.getStatus() == RuleStatus.ENABLED)
					rule.setOperation(Operation.ENABLE);
				else 
					rule.setOperation(Operation.DISABLE);
				OrganCustomParam organCustomParam;
				
				rules.add(rule);
			}
		}
 */
		return rules;
	}

	public static final int base_param_num = 3;
	
	public static final String obtainDrlPackageName(String organNo) {
		return "package_" + organNo;
	}

	public void buildRuleText(RuleInEngine rule) throws UnsupportedException {
		List<OrganCustomParam> params = rule.getParams();
		Object[] arguments = new Object[params.size() + base_param_num];

		// 基础参数：规则包名，规则名，机构
		arguments[0] = obtainDrlPackageName(rule.getOrganNo());
		arguments[1] = rule.getRuleTemplate().getCode();
		arguments[2] = rule.getOrganNo();

		for (int i = 0; i < params.size(); i++) {
			OrganCustomParam ruleParam = params.get(i);
			arguments[i + base_param_num] = ruleParam.build().getConvertedValue();
		}

		String text = rule.getRuleTemplate().getRuleText();
		String realText = MessageFormat.format(text, arguments);
		System.out.println("buildRuleText:\n" + realText);
		rule.setRuleText(realText);
	}
	
	
	private Map<Long, RuleTemplate> toMap1(List<RuleTemplate> ruleTemplates) {
		Map<Long, RuleTemplate> map = new HashMap<Long, RuleTemplate>();
		for (RuleTemplate ruleTemplate : ruleTemplates) {
			Long key = ruleTemplate.getId();
			map.put(key, ruleTemplate);
		}
		return map;
	}
	
	/**
	 * @param ruleParams
	 * @return
	 */
	private Map<Long, List<RuleParam>> toMap2(List<RuleParam> ruleParams) {
		Map<Long, List<RuleParam>> map = new HashMap<Long, List<RuleParam>>();
		for (RuleParam ruleParam : ruleParams) {
			Long key = ruleParam.getRuleTemplateId();
			List<RuleParam> temp = map.get(key);
			if(temp == null) {
				temp = new ArrayList<RuleParam>();
				map.put(key, temp);
			}
			temp.add(ruleParam);
		}
		
		for (Entry<Long,List<RuleParam>> entry : map.entrySet()) {
			List<RuleParam> list = entry.getValue();
			Collections.sort(list);
		}
		return map;
	}
	
	/**
	 * @param organCustomParams
	 * @return
	 */
	private Map<String, OrganCustomParam> toMap3(List<OrganCustomParam> organCustomParams) {
		Map<String, OrganCustomParam> map = new HashMap<String, OrganCustomParam>();
		for (OrganCustomParam organCustomParam : organCustomParams) {
			String key = organCustomParam.getOrganNo() + "&" + organCustomParam.getRuleParamId();
			map.put(key, organCustomParam);
		}
		return map;
	}

	public Set<RuleInEngine> buildRulesForEnginRefresh() throws UnsupportedException {
		//模版启用、停用、参数修改，机构配置启用、停用、参数修改
		
		Set<RuleInEngine> rules = null;
		return rules;

	}
	
	/**
	 * @param ruleService the ruleService to set
	 */
	public void setRuleService(RuleService ruleService) {
		this.ruleService = ruleService;
	}


}
